<script setup lang="ts">
  import { ref, computed, watch } from 'vue';
  import { PlusOutlined } from '@ant-design/icons-vue';
  import { message, Upload } from 'ant-design-vue';
  import type { UploadFile, UploadProps } from 'ant-design-vue';
  import Api from '@/api';
  import helper from '@/utils/helper';

  defineOptions({
    name: 'AvatarUpload',
    inheritAttrs: false,
  });

  type FileType = Parameters<NonNullable<UploadProps['beforeUpload']>>[0];

  const modelValue = defineModel<string>('value');

  const fileList = ref<UploadFile[]>([]);
  const previewVisible = ref(false);
  const previewImage = ref('');
  const previewTitle = ref('');

  const avatarUrl = computed(() => {
    // 简单处理，如果有modelValue值就使用baseApiUrl + modelValue，否则使用默认图标
    return modelValue.value ? (helper.toApiUrl("file/download2?md5=" + modelValue.value)) : '';
  });

  const stop = watch(modelValue, (avatar) => {
    if (avatar && !fileList.value.length) {
      fileList.value = [
        {
          uid: `vc-upload-${Date.now()}-1`,
          name: avatar.split('/').at(-1)!,
          status: 'done',
          url: avatarUrl.value,
        },
      ];
      stop();
    }
  });

  const beforeUpload = (file: FileType) => {
    const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
    if (!isJpgOrPng) {
      message.error('您只能上传JPG/PNG格式的图片!');
    }
    const isLt2M = file.size / 1024 / 1024 < 2;
    if (!isLt2M) {
      message.error('图片必须小于2MB!');
    }

    return isJpgOrPng && isLt2M;
  };

  const uploadAvatar = async (file: FileType) => {
    try {
      // 显示上传中的提示
      const hide = message.loading('头像上传中...', 0);
      
      // 使用file.ts中封装的切片上传方法
      const result = await Api.file.uploadAvatar(file);
      
      // 关闭加载提示
      hide();
      
      if (result && result.md5) {
        // 更新模型值（文件的MD5值）
        modelValue.value = result.md5;
        // 显示上传成功提示
        message.success('头像上传成功!');
        return result;
      } else {
        throw new Error('上传失败');
      }
    } catch (error) {
      message.error('头像上传失败');
      console.error('Avatar upload error:', error);
      throw error;
    }
  };

  const customRequest: UploadProps['customRequest'] = async (options) => {
    try {
      await uploadAvatar(options.file as FileType);
      if (options.onSuccess) {
        options.onSuccess({});
      }
    } catch (error) {
      if (options.onError) {
        options.onError(error as Error);
      }
    }
  };

  const handleChange: UploadProps['onChange'] = ({ file }) => {
    console.log('onChange', file);
    // 只在上传成功后更新文件列表
    if (file.status === 'done') {
      fileList.value = [file];
    }
  };

  const handleRemove: UploadProps['onRemove'] = (file) => {
    console.log('handleRemove', file);
    modelValue.value = '';
    fileList.value = [];
  };

  const handleCancel = () => {
    previewVisible.value = false;
    previewTitle.value = '';
  };
  const handlePreview = async (file: UploadFile) => {
    if (!file.url && !file.preview) {
      file.preview = avatarUrl.value;
    }
    previewImage.value = file.url || (file.preview as string);
    previewVisible.value = true;
    previewTitle.value = file.name || file.url!.substring(file.url!.lastIndexOf('/') + 1);
  };
</script>

<template>
  <Upload
    :file-list="fileList"
    name="avatar"
    list-type="picture-card"
    class="min-h-[110px]"
    :custom-request="customRequest"
    @before-upload="beforeUpload"
    @change="handleChange"
    @remove="handleRemove"
    @preview="handlePreview"
  >
    <div v-if="fileList.length < 1">
      <PlusOutlined />
      <div style="margin-top: 8px">上传</div>
    </div>
  </Upload>
  <a-modal :open="previewVisible" :title="previewTitle" :footer="null" @cancel="handleCancel">
    <img alt="example" style="width: 100%" :src="previewImage" />
  </a-modal>
</template>

<style lang="less" scoped></style>
